/**
  ETFRoot project, Anyang Normal University && IMP-CAS
  \class ETFDetector
  \brief a general detector class, which can hold a list of sub-detectors, like
  the sturcture of the TTask. Note that this is an abstract base class
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-10-27
  \date 2021-11-30 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2021-10-27   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef ETFDetector_h
#define ETFDetector_h

#include <vector>
#include <TNamed.h>

class TGraph;
class ETFHPTDCChannel;
class ETFAmplitudeChannel;
class ETFHit;

using std::vector;

class ETFDetector : public TNamed{
public:
  ETFDetector(){}
  ETFDetector(const char *name);
  virtual ~ETFDetector();

  virtual void Initialize(); ///< initialize the detector
  virtual void Assign(const ETFHPTDCChannel *ch) = 0; ///< add an HPTDC channel to detector
  virtual void Assign(const ETFAmplitudeChannel *ch){} ///< add a amplitude channel to detector
  virtual void Reset(){ Initialize(); }
  virtual void TransformToLabRef(double *p) const;
  virtual void TransformToLabRef(ETFHit *h) const;
  virtual void Draw(); ///< draw the detector and highlight the hits
  virtual void DrawHits(){} ///< draw the hits
  virtual void ConstructGraph(){} ///< add all detecting units to fGDumb
  /// chIdMap[chid] = uid; \param overwrite true then re-writing check is skipped
  void SetChIdMap(int chid, unsigned uid, bool overwrite = false);
  ///< \return if ch is within time window around the trig, to filter multihit
  virtual bool TrigBoundCheck(ETFHPTDCChannel *ch);
  virtual void Register() = 0; ///< register hits to the main output tree

  /// \param p1[0-4]: {k, b, k2, b2}; p: the hit point
  virtual void GetHitPosition(const double *p1, double *p, bool ifY = false);
  /// \param p1[0-4]: {k, b, k2, b2}; (lx,ly): distance from the hit to det center
  virtual void GetHitPositionL(const double *p1, double &lx, double &ly);
  virtual void GetHitPositionL(const double *p1, double &lx);
  void GetPosition(double *p) const; ///< \return the center of the detector
  double GetX() const{ return fPos[0]; }
  double GetY() const{ return fPos[1]; }
  double GetZ() const{ return fPos[2]; }
  void GetAng(double *a) const;
  double GetPhi() const{ return fAng[0]; }
  int GetDetId() const{ return fDetId; }
  double GetDelay() const{ return fDelay; }
  virtual void Print(); ///< print the detector info

  ClassDef(ETFDetector, 1); ///< general class for detectors

protected:
  int fDetId; ///< global detector ID upon constrcution
  double fDelay; ///< delay time for all the sense wires in the DC
  double fTrigLB, fTrigHB; ///< [low_bound+trig, high_bound+trig]
  /// detector position and orientation ///
  double fPos[3], fAng[3]; ///< [X,Y,Z], [phi,theta,psi]
  TGraph *fGDumb; //! ///< graphs for the dumb det unit
};

#endif
